package cn.wolfcode.service.impl;

import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.feign.ProductFeignApi;
import cn.wolfcode.mapper.SeckillProductMapper;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.ISeckillProductService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service
@Slf4j
public class SeckillProductServiceImpl implements ISeckillProductService {
    @Autowired
    private SeckillProductMapper seckillProductMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ProductFeignApi productFeignApi;

    @Override
    public List<SeckillProductVo> querySeckillProductByTime(int time) {
        //创建秒杀商品封装对象集合
        List<SeckillProductVo> voList = new ArrayList<>();
        //查看秒杀商品信息
        List<SeckillProduct> seckillProductList = seckillProductMapper.queryCurrentlySeckillProduct(time);
        if(seckillProductList != null && seckillProductList.size() > 0){
            List<Long> ids = new ArrayList<>();
            for (SeckillProduct seckillProduct : seckillProductList) {
                ids.add(seckillProduct.getProductId());
            }
            //根据秒杀商品id集合获取商品基本信息集合
            Result<List<Product>> result = productFeignApi.queryProductByIds(ids);
            if(result != null && !result.hasError()){
                List<Product> productList = result.getData();
                Map<Long, Product> map = new HashMap<>();
                for (Product product : productList) {
                    map.put(product.getId(), product);
                }
                //将秒杀商品信息封装到vo对象
                for (SeckillProduct seckillProduct : seckillProductList) {
                    Product product = map.get(seckillProduct.getProductId());
                    SeckillProductVo vo = new SeckillProductVo();
                    BeanUtils.copyProperties(product, vo);
                    BeanUtils.copyProperties(seckillProduct, vo);
                    voList.add(vo);
                }
            }
        }
        return voList;
    }

    @Override
    public List<SeckillProductVo> queryByTime(int time) {
        List<Object> values = redisTemplate.opsForHash().values(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""));
        List<SeckillProductVo> voList = JSON.parseArray(values.toString(), SeckillProductVo.class);
        if(voList != null && voList.size() > 0){
            return voList;
        }
        return Collections.emptyList();
    }

    @Override
    public SeckillProductVo find(int time, Long seckillId) {
        Object voStr = redisTemplate.opsForHash().get(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""), seckillId.toString());
        return JSON.parseObject(voStr.toString(), SeckillProductVo.class);
    }

    @Override
    @Transactional
    public int decrStockCount(Long seckillId) {
        return seckillProductMapper.decrStock(seckillId);
    }


    @Override
    public void stockCountBack(Long seckillId) {
        seckillProductMapper.incrStock(seckillId);
    }


    @Override
    public void syncRedisStockCount(Long seckillId, Integer time) {
        //回滚库存,查询数据库中的真实库存更新redis中的数据
        int count = seckillProductMapper.getStockCount(seckillId);
        redisTemplate.opsForHash().put(
                SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(time+""), seckillId+"", count+"");
        log.info("预库存回补成功");
    }
}
